package biz.yfsoft.app.fastframework.kit;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.snaker.engine.SnakerEngine;
import org.snaker.engine.access.Page;
import org.snaker.engine.access.QueryFilter;
import org.snaker.engine.entity.Order;
import org.snaker.engine.entity.Task;
import org.snaker.engine.model.TaskModel.TaskType;
import org.snaker.jfinal.plugin.SnakerPlugin;

public class TaskKit {

	//待执行任务
	public static String FASEWORKESQL = "SELECT * FROM view_fast_work WHERE 1=1";
	
	//历史任务
	public static String HSITFASEWORKESQL = "SELECT * FROM view_hist_fast_work WHERE 1=1";
	
	//流程表
	public static String PROCESSSQL = "SELECT * FROM view_wf_process WHERE 1=1";
	
	//流程表
	public static String PROCESSSQLID = "SELECT ID FROM view_wf_process WHERE 1=1";
	/**
	 * 通过插件获取流程引擎入口
	 */
	private static SnakerEngine engine = SnakerPlugin.getEngine();
	
	
	/**
	 * 创建实例、任务并且启动
	 * @param processId	工作流的编号
	 * @param operator	创建者
	 * @param params	实例参数、任务参数
	 * @return
	 */
	public static Order startInstanceById(String processId, String operator, Map<String, Object> params){
		return engine.startInstanceById(processId, operator, params);
	}
	
	/**
	 * 执行任务
	 * @param taskId	任务编号
	 * @param operator	执行者
	 * @param params	执行参数
	 * @return
	 */
	public static List<Task> executeTask(String taskId, String operator, Map<String, Object> params){
		return engine.executeTask(taskId, operator, params);
	}
	
	/**
	 * 创建实例任务并且执行
	 * @param processId
	 * @param params
	 * @return
	 */
	public static Order startAndExecute(String processId, Map<String, Object> params){
		String operator = params.get("operator").toString();
		Map<String, Object> ps = new HashMap<String, Object>();
		ps.putAll(params);
		ps.put("actorId", operator);
		Order order = startInstanceById(processId, operator, ps);
		List<Task> tasks = engine.query().getActiveTasks(new QueryFilter().setOrderId(order.getId()).setOperator(operator));
		List<Task> newTasks = new ArrayList<Task>();
		if(tasks != null && tasks.size() > 0) {
			Task task = tasks.get(0);
			newTasks.addAll(executeTask(task.getId(), operator, params));
		}
		return order;
	}
	
	//转办
	public List<Task> transferMajor(String taskId, String operator, String... actors) {
		List<Task> tasks = engine.task().createNewTask(taskId, TaskType.Major.ordinal(), actors);
		engine.task().complete(taskId, operator);
		return tasks;
	}
	
	//协办
	public List<Task> transferAidant(String taskId, String operator, String... actors) {
		List<Task> tasks = engine.task().createNewTask(taskId, TaskType.Aidant.ordinal(), actors);
		engine.task().complete(taskId, operator);
		return tasks;
	}
	
	
	/**
	 * 查询（任务、实例、工作流、参与者）关联
	 * @param sql			数据库
	 * @param entryClass	实体类型
	 * @param page			分页
	 * @param params		参数
	 * @param orderFields	排序字段
	 * @param order			排序规则
	 * @return
	 */
	public static <T> T find(String sql, Class<T> entryClass, Map<String, Object> params){
		List<T> entites = query(sql, entryClass, params);
		if(entites != null && entites.size() == 1)
			return entites.get(0);
		return null;
	}
	
	public static <T> List<T> query(String sql, Class<T> entryClass, Map<String, Object> params){
		return query(sql, entryClass, null, params, null, null);
	}
	
	public static <T> List<T> query(String sql, Class<T> entryClass, Page<T> page, Map<String, Object> params, String orderFields, String order){
		StringBuffer sb = new StringBuffer(sql);
		Object[] o = new Object[(params!=null)?((orderFields!=null)?(params.size() + 2):params.size()):((orderFields!=null)?(2):0)];
		int i = 0;
		if(params != null){
			for (Iterator<String> iterator = params.keySet().iterator(); iterator.hasNext();) {
				String key = iterator.next();
				sb.append(" AND " + key + "=?");
				o[i++] = params.get(key);
			}
		}
		if(orderFields != null){
			sb.append(" ORDER BY ? ?");
			o[i++] = orderFields;
			o[i] = order;
		}
		System.out.println(params);
		if(page == null)
			return engine.query().nativeQueryList(entryClass, sb.toString(), o);
		return engine.query().nativeQueryList(page, entryClass, sb.toString(), o);
	}
	
}
